﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Globalization;

using GMap.NET;
using GMap.NET.WindowsForms;
using GMap.NET.WindowsForms.Markers;
using GMap.NET.WindowsForms.ToolTips;
using GMap.NET.MapProviders;

using System.Diagnostics;
using VehicleTrackingProject.Classes;

namespace VehicleTrackingProject.Forms
{
    public partial class frmVehicleTracking : Form
    {
        // marker
        GMapMarker currentMarker;
        //show/hide center marker (image is plus sign)
        GMapMarker center;

        // polygons
        GMapPolygon polygon;
        internal readonly GMapOverlay objects = new GMapOverlay("objects");
        internal readonly GMapOverlay routes = new GMapOverlay("routes");
        internal readonly GMapOverlay polygons = new GMapOverlay("polygons");

        // layers
        readonly GMapOverlay top = new GMapOverlay();
        
        bool isMouseDown = false;

        public frmVehicleTracking()
        {
            InitializeComponent();

            // config map 
            mapControl.MapProvider = GMapProviders.YahooMap;
            mapControl.Position = new PointLatLng(54.6961334816182, 25.2985095977783);
            //mapControl.Position = new PointLatLng(0, 0);
            mapControl.MinZoom = mapControl.MapProvider.MinZoom;
            mapControl.MaxZoom = mapControl.MapProvider.MaxZoom.Value;
            mapControl.Zoom = 8;
            mapControl.ShowTileGridLines = true;

            //// map events
            mapControl.OnPositionChanged += new PositionChanged(MapControl_OnPositionChanged);
            //mapControl.OnTileLoadStart += new TileLoadStart(MapControl_OnTileLoadStart);
            //mapControl.OnTileLoadComplete += new TileLoadComplete(MapControl_OnTileLoadComplete);
            ////mapControl.OnMarkerClick += new MarkerClick(MapControl_OnMarkerClick);
            mapControl.OnMapZoomChanged += new MapZoomChanged(MapControl_OnMapZoomChanged);
            //mapControl.OnMapTypeChanged += new MapTypeChanged(MapControl_OnMapTypeChanged);
            //mapControl.MouseMove += new MouseEventHandler(MapControl_MouseMove);
            mapControl.MouseDown += new MouseEventHandler(MapControl_MouseDown);
            mapControl.MouseUp += new MouseEventHandler(MapControl_MouseUp);
            //mapControl.OnMarkerEnter += new MarkerEnter(MapControl_OnMarkerEnter);
            //mapControl.OnMarkerLeave += new MarkerLeave(MapControl_OnMarkerLeave);


            // add custom layers  
            {
                mapControl.Overlays.Add(objects);
                mapControl.Overlays.Add(polygons);
                mapControl.Overlays.Add(top);

                //objects.Markers.CollectionChanged += new GMap.NET.ObjectModel.NotifyCollectionChangedEventHandler(Markers_CollectionChanged);
            }

            // set current marker
            currentMarker = new GMarkerGoogle(mapControl.Position, GMarkerGoogleType.arrow);
            currentMarker.IsHitTestVisible = false;
            top.Markers.Add(currentMarker);

            currentMarker.IsVisible = checkBoxCurrentMarker.Checked;
            
        }

        // MapZoomChanged
        void MapControl_OnMapZoomChanged()
        {
            //trackBar1.Value = (int)(MainMap.Zoom);
            //textBoxZoomCurrent.Text = MainMap.Zoom.ToString();
            center.Position = mapControl.Position;
        }

        // current point changed
        void MapControl_OnPositionChanged(PointLatLng point)
        {
            center.Position = point;
            //textBoxLatCurrent.Text = point.Lat.ToString(CultureInfo.InvariantCulture);
            //textBoxLngCurrent.Text = point.Lng.ToString(CultureInfo.InvariantCulture);

            //lock (flights)
            //{
            //    lastPosition = point;
            //    lastZoom = (int)MainMap.Zoom;
            //}
        }

        void MapControl_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isMouseDown = false;
            }
        }
        
        void MapControl_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isMouseDown = true;

                //if (currentMarker.IsVisible)
                //{

                    currentMarker.Position = mapControl.FromLocalToLatLng(e.X, e.Y);

                    var px = mapControl.MapProvider.Projection.FromLatLngToPixel(currentMarker.Position.Lat, currentMarker.Position.Lng, (int)mapControl.Zoom);
                    var tile = mapControl.MapProvider.Projection.FromPixelToTileXY(px);

                    Debug.WriteLine("MouseDown: " + currentMarker.LocalPosition + " | geo: " + currentMarker.Position + " | px: " + px + " | tile: " + tile);
                //}

                if (!mapControl.CanDragMap)
                    AddMarker();
            }
        }

        private void button8_Click(object sender, EventArgs e)
        {
            double lat = double.Parse(textBoxLat.Text, CultureInfo.InvariantCulture);
            double lng = double.Parse(textBoxLng.Text, CultureInfo.InvariantCulture);
            mapControl.Position = new PointLatLng(lat, lng);
        }

        public enumGMapMarker marker;
        public void AddMarker()
        {
            GMapMarker m = null;
            GMapMarker mBorders = null;

            if (radioButtonRectangleMarker.Checked){
                m = new GMarkerGoogle(currentMarker.Position, GMarkerGoogleType.green);
                mBorders = new GMapMarkerRect(currentMarker.Position);
                {
                    (mBorders as GMapMarkerRect).InnerMarker = (GMarkerGoogle)m;
                    if (polygon != null)
                    {
                        mBorders.Tag = polygon.Points.Count;
                    }
                    mBorders.ToolTipMode = MarkerTooltipMode.Always;
                }
            }
            else if (radioButtonCircleMarker.Checked)
            {
                m = new GMarkerGoogle(currentMarker.Position, GMarkerGoogleType.red);
                mBorders = new GMapMarkerEllipse(currentMarker.Position);
                {
                    (mBorders as GMapMarkerEllipse).InnerMarker = (GMarkerGoogle)m;
                    if (polygon != null)
                    {
                        mBorders.Tag = polygon.Points.Count;
                    }
                    mBorders.ToolTipMode = MarkerTooltipMode.Always;
                }
            }
            else if (radioButtonStarMarker.Checked)
            {
                m = new GMarkerGoogle(currentMarker.Position, GMarkerGoogleType.green);
                mBorders = new GMapMarkerStar(currentMarker.Position);
                {
                    (mBorders as GMapMarkerStar).InnerMarker = (GMarkerGoogle)m;
                    if (polygon != null)
                    {
                        mBorders.Tag = polygon.Points.Count;
                    }
                    mBorders.ToolTipMode = MarkerTooltipMode.Always;
                }
            }
            else if (radioButtonImageMarker.Checked)
            {
                mBorders = new GMapMarkerImage(currentMarker.Position);
                {
                    if (polygon != null)
                    {
                        mBorders.Tag = polygon.Points.Count;
                    }
                    mBorders.ToolTipMode = MarkerTooltipMode.Always;
                }
            }
            else if (radioButtonGreenGoogleMarker.Checked)
            {
                m = new GMarkerGoogle(currentMarker.Position, GMarkerGoogleType.green);
            }
            else if (radioButtonRedGoogleMarker.Checked)
            {
                m = new GMarkerGoogle(currentMarker.Position, GMarkerGoogleType.red);
            }

            Placemark p = null;
            if (chkPlaceMarkInfo.Checked)
            {
                GeoCoderStatusCode status;
                var ret = GMapProviders.GoogleMap.GetPlacemark(currentMarker.Position, out status);
                if (status == GeoCoderStatusCode.G_GEO_SUCCESS && ret != null)
                {
                    p = ret;
                }
            }
            if (m != null)
                objects.Markers.Add(m);

            if (mBorders != null)
            {
                if (p != null)
                {
                    mBorders.ToolTipText = p.Address;
                }
                else
                {
                    mBorders.ToolTipText = currentMarker.Position.ToString();
                }
                objects.Markers.Add(mBorders);
            }
            if (chkDrawPolygon.Checked)
                RegeneratePolygon();
        }

        public void RegeneratePolygon()
        {
            List<PointLatLng> polygonPoints = new List<PointLatLng>();

            foreach (GMapMarker m in objects.Markers)
            {
                //if (m is GMapMarkerRect || m is GMapMarkerEllipse || m is GMapMarkerStar || m is GMapMarkerImage)
                //{
                m.Tag = polygonPoints.Count;
                polygonPoints.Add(m.Position);
                //}
            }

            if (polygon == null)
            {
                polygon = new GMapPolygon(polygonPoints, "polygon test");
                polygons.Polygons.Add(polygon);
            }
            else
            {
                polygon.Points.Clear();
                polygon.Points.AddRange(polygonPoints);

                if (polygons.Polygons.Count == 0)
                {
                    polygons.Polygons.Add(polygon);
                }
                else
                {
                    mapControl.UpdatePolygonLocalPosition(polygon);
                }
            }
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            mapControl.CanDragMap = chkCanDragMap.Checked;
            if (mapControl.CanDragMap)
            {
                mapControl.DragButton = System.Windows.Forms.MouseButtons.Left;
                mapControl.Cursor = Cursors.Hand;
            }
            else
            {
                mapControl.Cursor = Cursors.Default;
            }
        }

        private void chkPlaceMarkInfo_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void chkDrawPolygon_CheckedChanged(object sender, EventArgs e)
        {
            
            
        }

        private void chkShowCenterMarker_CheckedChanged(object sender, EventArgs e)
        {
            center.IsVisible = chkShowCenterMarker.Checked;
        }

        private void checkBoxCurrentMarker_CheckedChanged(object sender, EventArgs e)
        {
            currentMarker.IsVisible = checkBoxCurrentMarker.Checked;
        }

        private void radioButtonStarMarker_CheckedChanged(object sender, EventArgs e)
        {

        }
    }
}
